import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class MaJiangHuPai_1 {

    public enum PAI {
        //万饼条
        W1(0), W2(1), W3(2), W4(3), W5(4), W6(5), W7(6), W8(7), W9(8),
        B1(9), B2(10), B3(11), B4(12), B5(13), B6(14), B7(15), B8(16), B9(17),
        T1(18), T2(19), T3(20), T4(21), T5(22), T6(23), T7(24), T8(25), T9(26),
        //东南西北中发白
        D(27), N(28), X(29), B(30), Zhong(31), Fa(32), Bai(33),
        ;
        private int v;

        private PAI(int v) {
            this.v = v;
        }

        public static PAI valueOf(int v) {
            for (PAI pai : values()) {
                if (v == pai.v) return pai;
            }
            return null;
        }
    }

    public static void main(String[] args) {
        List<PAI> list = Arrays.asList(
                PAI.W2, PAI.W3, PAI.W3,
                PAI.W4, PAI.W4, PAI.W4,
                PAI.W4, PAI.W5, PAI.W5,
                PAI.W5, PAI.W6, PAI.W6,
                PAI.Bai, PAI.Bai
        );
        long time2 = System.currentTimeMillis();
        boolean bool = false;
        for (int i = 0; i < 1000000; i++) {
            bool = isHuPai(list);
        }
        System.out.println("胡了：" + bool);
        System.out.println("耗时：" + (System.currentTimeMillis() - time2));
    }

    /**
     * 是否胡牌
     *
     * @param list
     * @return
     */
    public static boolean isHuPai(List<PAI> list) {
        //先排序
        List<PAI> sortList = new ArrayList<>(list);
        Collections.sort(sortList);
        //是否七对
        if (is7Dui(list))
            return true;
        //TODO 是否其他牌型
        for (int i = 0; i < sortList.size() - 1; i++) {
            if (sortList.get(i) == sortList.get(i + 1)) {
                List<PAI> newList = new ArrayList<>(sortList);
                //去掉对子
                newList.remove(i);
                newList.remove(i);
                boolean bool = digui(newList, false);
                if (bool)
                    return true;
            }
        }
        return false;
    }

    /**
     * 是否七对
     *
     * @param list
     * @return
     */
    private static boolean is7Dui(List<PAI> list) {
        for (int i = 0; i < list.size(); i += 2) {
            if (list.get(i) != list.get(i + 1))
                return false;
        }
        return true;
    }

    /**
     * 递归计算
     *
     * @param list 除掉将牌(对子)后的牌
     * @param bool 一手牌同为顺子、刻子时，默认（顺子方向）未胡牌时，走另一条方向的标记
     * @return
     */
    private static boolean digui(List<PAI> list, boolean bool) {
        if (list.size() == 0) {
            return true;
        }
        List<PAI> newList = new ArrayList<>(list);
        PAI first = newList.remove(0);
        int shun_2 = newList.indexOf(PAI.valueOf(first.v + 1));
        int shun_3 = newList.indexOf(PAI.valueOf(first.v + 2));
        int ke_2 = newList.indexOf(PAI.valueOf(first.v));
        int ke_3 = newList.lastIndexOf(PAI.valueOf(first.v));
        //是否顺子，刻子
        boolean isShunZi = shun_2 != -1 && shun_3 != -1 && first.v <= PAI.T7.v;
        boolean isKeZi = ke_2 != -1 && ke_3 != -1 && ke_2 != ke_3;
        if (!isShunZi && !isKeZi) {
            //非顺子，非刻子，即未胡牌
            return false;
        } else if (isShunZi && !isKeZi) {
            //是顺子，非刻子，删除对应的顺子牌型，先从后面的下标删除
            newList.remove(shun_3);
            newList.remove(shun_2);
            return digui(newList, false);
        } else if (!isShunZi && isKeZi) {
            //非顺子，是刻子，删除对应的刻子牌型，先从后面的下标删除
            newList.remove(ke_3);
            newList.remove(ke_2);
            return digui(newList, false);
        } else {
            //是顺子，也是刻子
            //默认(bool=false)是先查顺子，后查刻子，若是bool=true，则反之
            if (bool) {
                newList.remove(ke_3);
                newList.remove(ke_2);
                return digui(newList, false);
            } else {
                newList.remove(shun_3);
                newList.remove(shun_2);
                boolean bo = digui(newList, false);
                if (bo) {
                    //默认顺子方向，已经胡牌
                    return true;
                }
                //默认未胡牌时，则走刻子方向
                return digui(list, true);
            }
        }
    }

}
